package com.frontend.trade.Service.Impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.frontend.trade.Service.QRCodeService;
import com.frontend.trade.wechat.WeChatResponse;
import com.frontend.trade.model.Trading;
import com.frontend.trade.wechat.WechatPayHttpClient;
import com.order.frontend.feginapi.trade.enums.PayChannelEnum;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.security.PrivateKey;
import java.util.Map;



public class WeChatPayService {



    public WeChatPayService() {

    }

    WechatPayHttpClient client = new  WechatPayHttpClient();

    public Trading   createDownLineTrading(Trading tradingEntity) {
        //请求地址
        String apiPath = "/v3/pay/transactions/native";
        //请求参数
        Map<String, Object> params = MapUtil.<String, Object>builder()
                .put("mchid", client.getMchId())
                .put("appid", client.getAppId())
                .put("description", tradingEntity.getMemo())
                .put("notify_url", client.getNotifyUrl())
                .put("out_trade_no", Convert.toStr(tradingEntity.getTradingOrderNo()))
                .put("amount", MapUtil.<String, Object>builder()
                        .put("total", Convert.toInt(NumberUtil.mul(tradingEntity.getTradingAmount(), 100))) //金额，单位：分
                        .put("currency", "CNY") //人民币
                        .build())
                .build();
        try {
            WeChatResponse response = doPost(apiPath, params);
            tradingEntity.setPlaceOrderCode(Convert.toStr(response.getStatus()));
            //二维码需要展现的信息
            tradingEntity.setPlaceOrderMsg(JSONUtil.parseObj(response.getBody()).getStr("code_url"));
            //指定统一下单json字符串
            tradingEntity.setPlaceOrderJson(JSONUtil.toJsonStr(response));
            QRCodeService  qrCodeService = new QRCodeServiceImpl();
            String generate = qrCodeService.generate(tradingEntity.getPlaceOrderMsg(), PayChannelEnum.WECHAT_PAY);
            tradingEntity.setQrCode(generate);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return tradingEntity;
    }





    public WeChatResponse doPost(String apiPath, Map<String, Object> params) throws Exception {
        String url = StrUtil.format("https://{}{}", client.getDomain(), apiPath);
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");

        String body = JSONUtil.toJsonStr(params);
        httpPost.setEntity(new StringEntity(body, CharsetUtil.UTF_8));

        CloseableHttpResponse response = createHttpClient().execute(httpPost);
        return new WeChatResponse(response);
    }

    public CloseableHttpClient createHttpClient() throws Exception {
        // 加载商户私钥（privateKey：私钥字符串）
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(client.getPrivateKey().getBytes("utf-8")));

        // 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3密钥）
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(client.getMchSerialNo(), merchantPrivateKey);
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(
                client.getMchId(), privateKeySigner);

        // 向证书管理器增加需要自动更新平台证书的商户信息
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(client.getMchId(), wechatPay2Credentials, client.getApiV3Key().getBytes("utf-8"));

        // 初始化httpClient
        return com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder.create()
                .withMerchant(client.getMchId(), client.getMchSerialNo(), merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(client.getMchId())))
                .build();
    }





}
